[UE]PushModel属性同步
PushModel属性同步
优势
PushModel
是对 Replicate
的一个优化。
对于属性的同步,原有的 Replicated
属性,在 Replicate
之前需要通过反射
对一个 Actor
的所有属性进行 diff
,对比所有的属性是否发生变化,变化的属性才进行同步。
而用上了 PushModel
,我们可以主动 MARK_DIRTY
,在 Set
时主动将其设置为脏,相当于给该属性上了一个Flag
,底层会自动通过这个Flag
来判断是否需要同步,省去了 diff
这个高消耗的操作。
需要注意的是,对于一个 Actor
,如果采用了 PushModel
,则需要将所有需要同步的属性都挂上这个 PushModel
,否则如果存在非PushModel
的需要Repilicated
的属性,可能会该功能不生效,退化到原来的情况。
UE5 中还对 PushModel
做了更进一步的优化,添加了一些新的宏以及对更多基础组件的支持。
实践
设置依赖
首先,我们需要在 Build.cs
中添加 NetCore
模块的依赖。
1 | PublicDependcyModuleNames.AddRange(new string[] {"NetCore"}) |
设置属性
我们对于一个需要同步的属性,得先加上 Replicated
标签;有必要的话,需要加上RepilicatedUsing
来设置属性为脏时执行的回调函数。
1 | UCLASS() |
1 | void ATest::OnRep_Param() {...} |
声明同步
首先我们要先将这个 Actor
标记为需要同步,在构造函数中标记 bReplicates = true
。
接着我们需要实现 GetLifetimeReplicatedProps
,在这个接口中添加宏标记同步的 Property。
1 | void ATest::GetLifetimeReplicatedProps(TArray< FLifetimeProperty >& OutLifetimeProps) const |
FDoRepLifetimeParams
中设置了同步的条件,其中bIsPushBased
表明是否使用 PushModel
。
其中 DOREPLIFETIME_WITH_PARAMS_FAST
的宏实现:
1 | define DOREPLIFETIME_WITH_PARAMS_FAST(c,v,params) \ |
修改属性
最后,我们在修改属性的时候,可以使用 MARK_PROPERTY_DIRTY_FROM_NAME
来将属性设脏。
1 | void ATest::SetParam(const float NewParam) |
现在,Server
只需要检测属性是否被 MARK_DIRTY
就可以知道是否需要同步。
当然,除了 MARK_PROPERTY_DIRTY_FROM_NAME
以外,UE 还实现了一些作用类似的其它的宏:
1 |
改进
当然,我们也可以不这么复杂,我们可以自己设置一个新的标签。
对于打上这个标签的属性,让其在 CodeGenerator
中自动生成 Setter
与 Getter
,然后通过 Setter
与 Getter
来进行修改与访问。
1 | template<typename _T> \ |
参考
Unreal Engine 4. New network model: PushModel:https://tech-en.netlify.app/articles/en539604/index.html